﻿using System;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using static System.String;
using IValueProvider = System.Web.Mvc.IValueProvider;
using System.Diagnostics;

namespace Sharp.Portal.Mvc
{
    [DebuggerStepThrough]
    public sealed class JsonDotNetValueProviderFactory : ValueProviderFactory
    {
        private static readonly JsonSerializerSettings JsonSettings;
        static JsonDotNetValueProviderFactory()
        {
            JsonSettings = new JsonSerializerSettings
            {
                MissingMemberHandling = MissingMemberHandling.Ignore,
                NullValueHandling = NullValueHandling.Ignore,
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                DefaultValueHandling = DefaultValueHandling.Include,
                Error = delegate (object obj, Newtonsoft.Json.Serialization.ErrorEventArgs args)
                { 
                    args.ErrorContext.Handled = true;
                }
            };
            //解决时间毫秒精度太高，ie9或更低浏览器无法识别。
            IsoDateTimeConverter datetimeConverter = new IsoDateTimeConverter
            {
                DateTimeFormat = "yyyy/MM/dd HH:mm:ss"
            };
            JsonSettings.Converters.Add(datetimeConverter);
        }
        public override IValueProvider GetValueProvider(ControllerContext controllerContext)
        {
            if (controllerContext == null)
                throw new ArgumentNullException(nameof(controllerContext));

            if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
                return null;

            var reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
            var bodyText = reader.ReadToEnd();
            reader.Close();

            return IsNullOrEmpty(bodyText)
                ? null
                : new DictionaryValueProvider<object>(
                    JsonConvert.DeserializeObject<ExpandoObject>(bodyText, JsonSettings), CultureInfo.CurrentCulture);
        }
    }
}